﻿using System;

namespace Yuchen.NPA.Core.CompilerService.RegularExpression
{
    internal class ExpressionVisitor
    {
        public virtual void Visit(Node node)
        {
            switch (node.Type)
            {
                case NodeType.Char:
                    Visit((CharNode)node);
                    break;
                case NodeType.Concat:
                    Visit((ConcatNode)node);
                    break;
                case NodeType.Escape:
                    Visit((EscapeNode)node);
                    break;
                case NodeType.Group:
                    Visit((GroupNode)node);
                    break;
                case NodeType.Selection:
                    Visit((SelectionNode)node);
                    break;
                case NodeType.Star:
                    Visit((StarNode)node);
                    break;
                case NodeType.Union:
                    Visit((UnionNode)node);
                    break;
                default:
                    throw new NotImplementedException("意外的类型：" + node.Type.ToString());
            }
        }

        public virtual void Visit(UnionNode node)
        {
            var leftNode = node.Children[0];
            var rightNode = node.Children[1];
            Visit(leftNode);
            Visit(rightNode);
        }

        public virtual void Visit(StarNode node)
        {
            Visit(node.Children[0]);
        }

        public virtual void Visit(CharNode node)
        {
            switch (node.Type)
            {
                case NodeType.Char:
                    break;
                case NodeType.Escape:
                    Visit((EscapeNode)node);
                    break;
                default:
                    throw new NotImplementedException("意外的类型：" + node.Type.ToString());
            }
        }

        public virtual void Visit(ConcatNode node)
        {
            var leftNode = node.Children[0];
            var rightNode = node.Children[1];
            Visit(leftNode);
            Visit(rightNode);
        }

        public virtual void Visit(EscapeNode node)
        {

        }

        public virtual void Visit(GroupNode node)
        {
            foreach (var nodeChild in node.Children)
            {
                Visit(nodeChild);
            }
        }

        public virtual void Visit(SelectionNode node)
        {
            foreach (var nodeChild in node.Children)
            {
                Visit(nodeChild);
            }
        }
    }
}
